﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.DAL
{
    public static class AmenazasFactory
    {
        //Método que inserta una nueva amenaza
        public static void InsertarAmenazas(Amenazas NuevaAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToAmenazasEstablecer(NuevaAmenaza);
            agenteBD.SaveChanges();
        }

        //Método que devuelve el identificador de un tipo de amenaza por su nombre
        public static int BuscarIdTipoAmenaza(String TipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdTipoAmenaza = from TAmenaza in agenteBD.TiposAmenazasEstablecer
                                            where TAmenaza.TipoAmenaza == TipoAmenaza
                                            select TAmenaza.IdTipoAmenaza;
            if (IdTipoAmenaza.Count() == 0)
            {
                return -1;
            }
            else
            {
                return IdTipoAmenaza.First();
            }
        }

        //Devuelve el nombre de una amenaza por su identificador
        public static String NombreAmenaza(int IdAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreAmenaza = from NAmenaza in agenteBD.AmenazasEstablecer
                                               where NAmenaza.IdAmenaza == IdAmenaza
                                               select NAmenaza.Amenaza;
            if (NombreAmenaza.Count() == 0)
            {
                return "";
            }
            else
            {
                return NombreAmenaza.First();
            }
        }

        //Devuelve el identificador de una amenaza por su nombre
        public static int BuscarIdAmenaza(String NombreAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdAmenaza = from NAmenaza in agenteBD.AmenazasEstablecer
                                        where NAmenaza.Amenaza == NombreAmenaza
                                        select NAmenaza.IdAmenaza;
            if (IdAmenaza.Count() == 0)
            {
                return -1;
            }
            else
            {
                return IdAmenaza.First();
            }
        }

        //Indica si el nombre de la amenaza que se pasa por parámetros está en la base de conocimiento
        public static bool EstaAmenaza(String NAmenaza)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreAmenaza = from TAmenaza in agenteBD.AmenazasEstablecer
                                               select TAmenaza.Amenaza;
            foreach (String s in NombreAmenaza)
            {
                if (NAmenaza.Equals(s.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    esta = true;
                }
            }
            return esta;
        }

        //Número de amenazas totales (disponibles y no) de la base de conocimiento
        public static int AmenazasTotales()
        {
            int numeroAmenazas = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Amenazas> AmenTotal = from Amen in agenteBD.AmenazasEstablecer
                                             select Amen;
            foreach (Amenazas Amen in AmenTotal)
            {
                numeroAmenazas++;
            }
            return numeroAmenazas;
        }

        //Método que hace un borrado lógico de todas las Amenazas dependientes de un tipo de amenaza
        public static List<Amenazas> EliminaAmenazasPorTipoAmenaza(int IdTipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las Amenazas actuales en la Base de Conocimiento
            List<Amenazas> LAmenazas = new List<Amenazas>();
            IQueryable<Amenazas> AmenazasTipAmen = from Amen in agenteBD.AmenazasEstablecer
                                                   where Amen.IdTipoAmenaza == IdTipoAmenaza && Amen.Actual == true
                                                   select Amen;
            if (AmenazasTipAmen.Count() != 0)
            {
                //Para cada uno actualizamos el Valor Actual a false
                foreach (Amenazas A in AmenazasTipAmen)
                {
                    A.Actual = false;
                    LAmenazas.Add(A);
                }
                agenteBD.SaveChanges();
            }
            //Si no había Amenazas dependientes devolvemos la fila vacía
            return LAmenazas;
        }

        //Método que recoge las Amenazas Actuales de la base de conocimiento
        public static List<Amenazas> AmenazasActuales()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<Amenazas> LAmenazas = new List<Amenazas>();
            IQueryable<Amenazas> Amenazas = (from Amen in agenteBD.AmenazasEstablecer
                                             where Amen.Actual == true
                                             select Amen).OrderBy(a => a.IdAmenaza);
            if (Amenazas.Count() != 0)
            {
                LAmenazas = Amenazas.ToList();
            }
            return LAmenazas;
        }

        //Método que actualiza una amenaza de la base de conocimiento
        public static void ActualizaAmenaza(int IdAmenaza, string Amenaza, int IdTipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var AmenActualiz = (from Amen in agenteBD.AmenazasEstablecer
                                where Amen.IdAmenaza == IdAmenaza
                                select Amen).Single();
            AmenActualiz.Amenaza = Amenaza;
            AmenActualiz.IdTipoAmenaza = IdTipoAmenaza;
            agenteBD.SaveChanges();
        }

        //Método que hace un borrado (lógico) de una amenaza, así como de todos los elementos que la contengan en la base de conocimiento
        public static void EliminaAmenaza(int IdAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Amenazas AmenElim = (from Amen in agenteBD.AmenazasEstablecer
                                 where Amen.IdAmenaza == IdAmenaza
                                 select Amen).Single();
            AmenElim.Actual = false;
            agenteBD.SaveChanges();
            //Lista de Amenazas. Añadimos a la lista la Amenaza recientemente eliminada
            List<Amenazas> LAmenazas = new List<Amenazas>();
            //Añado la Amenaza Eliminada
            LAmenazas.Add(AmenElim);
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Amenazas
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorAmenaza = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            //Lista de Relaciones Amenazas - Controles por Amenazas
            List<Matriz_Amenazas_Controles> LRelAmenControlPorAmenaza = new List<Matriz_Amenazas_Controles>();
            //Lista de Relaciones Amenazas - Vulnerabilidades por Amenazas
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulnPorAmenaza = new List<Matriz_AmenazasVulnerabilidades>();
            //Lista de Instancia Tipos Activos - Amenazas - Criterios de Riesgo por relaciones Tipos Activos - Amenazas - Criterios Riesgo
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas de primer nivel de dependencia con la Amenaza eliminada y actualizamos Actual
            //Nivel 1 de Dependencia
            //Matriz_TipoActivosAmenazasCriterioRiesgo
            LRelTipActAmenCritPorAmenaza = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.EliminaRelacionesPorAmenaza(LAmenazas);
            //Matriz_Amenazas_Controles
            LRelAmenControlPorAmenaza = Matriz_Amenazas_ControlesFactory.EliminaRelacionesPorAmenaza(LAmenazas);
            //Matriz Amenazas_Vulnerabilidades
            LRelAmenVulnPorAmenaza = Matriz_AmenazasVulnerabilidadesFactory.EliminaRelacionesPorAmenaza(LAmenazas);
            //Nivel 2 de Dependencia
            if (LRelTipActAmenCritPorAmenaza.Count() != 0)
            {
                //Instancias Tipo Activo - Amenaza - Criterio de Riesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorAmenaza);
            }
        }

        //Método que sirve para restaurar una lista de Amenazas y todo el conocimiento relacionado con ellas
        public static void RestauraAmenaza(List<int> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdAmenaza in LAmenazas)
            {
                //Restauramos la Amenaza
                Amenazas AmenRestaurar = (from Amen in agenteBD.AmenazasEstablecer
                                          where Amen.IdAmenaza == IdAmenaza
                                          select Amen).Single();
                AmenRestaurar.Actual = true;
                //Restauramos el Tipo de Amenaza Asociada
                TiposAmenazas TipAmenRest = (from Amen in agenteBD.AmenazasEstablecer
                                             join TipAmen in agenteBD.TiposAmenazasEstablecer on Amen.IdTipoAmenaza equals TipAmen.IdTipoAmenaza
                                             where Amen.IdAmenaza == IdAmenaza
                                             select TipAmen).Single();
                TipAmenRest.Actual = true;
            }
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Amenazas
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorAmenaza = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            //Lista de Relaciones Amenazas - Controles por Amenazas
            List<Matriz_Amenazas_Controles> LRelAmenControlPorAmenaza = new List<Matriz_Amenazas_Controles>();
            //Lista de Relaciones Amenazas - Vulnerabilidades por Amenazas
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulnPorAmenaza = new List<Matriz_AmenazasVulnerabilidades>();
            //Lista de Instancia Tipos Activos - Amenazas - Criterios de Riesgo por relaciones Tipos Activos - Amenazas - Criterios Riesgo
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas de primer nivel de dependencia con el IdAmenaza a Restaurar y actualizamos Actual
            //Nivel 1 de Dependencia
            //Matriz_TipoActivosAmenazasCriterioRiesgo
            LRelTipActAmenCritPorAmenaza = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.RestauraRelacionesPorAmenaza(LAmenazas);
            //Matriz_Amenazas_Controles
            LRelAmenControlPorAmenaza = Matriz_Amenazas_ControlesFactory.RestauraRelacionesPorAmenaza(LAmenazas);
            //Matriz Amenazas_Vulnerabilidades
            LRelAmenVulnPorAmenaza = Matriz_AmenazasVulnerabilidadesFactory.RestauraRelacionesPorAmenaza(LAmenazas);
            //Nivel 2 de Dependencia
            if (LRelTipActAmenCritPorAmenaza.Count() != 0)
            {
                //Instancias Tipo Activo - Amenaza - Criterio de Riesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.RestauraInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorAmenaza);
            }
            agenteBD.SaveChanges();
        }


        //Método que restaura todas las Amenazas dependientes de un Id Tipo de Amenaza
        internal static List<int> RestauraAmenazasPorTipoAmenaza(int IdTipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las Amenazas actuales en la Base de Conocimiento
            List<int> LAmenazasRestauradas = new List<int>();
            IQueryable<Amenazas> AmenazasTipAmen = from Amen in agenteBD.AmenazasEstablecer
                                                   where Amen.IdTipoAmenaza == IdTipoAmenaza
                                                   select Amen;
            if (AmenazasTipAmen.Count() != 0)
            {
                //Para cada uno actualizamos el Valor Actual a true
                foreach (Amenazas A in AmenazasTipAmen)
                {
                    A.Actual = true;
                    LAmenazasRestauradas.Add(A.IdAmenaza);
                }
                agenteBD.SaveChanges();
            }
            //Si no había Amenazas dependientes devolvemos la fila vacía
            return LAmenazasRestauradas;
        }


        //Método que Restaura una lista de Amenazas a través de una lista de sus Ids
        internal static void RestauraAmenazaPorRelaciones(List<int> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdAmenaza in LAmenazas)
            {
                //Restauramos la Amenaza
                Amenazas AmenRestaurar = (from Amen in agenteBD.AmenazasEstablecer
                                          where Amen.IdAmenaza == IdAmenaza
                                          select Amen).Single();
                AmenRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
        }

        //Devuelve el número de Amenazas actuales de la Base de Conocimiento
        public static int NumeroTotalAmenazas()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NAmenazas = (from Amenaza in agenteBD.AmenazasEstablecer
                             where Amenaza.Actual==true
                             select Amenaza).Count();
            return NAmenazas;
        }
    }
}
